define(['common/geometry/geometry2d', 'common/breeze/inputconstants'],
       function(geometry2d, inputconstants) {

function GamepadController(resetInputPass) {
  resetInputPass.addCallback(this.onResetInputPass_.bind(this));
  this.buttonIdToEvents_ = {};
  this.vectorIdToInfo_ = {};
  this.buttonIdToIndex_ = {};
  this.buttonIdToDown_ = {};
};

GamepadController.prototype.getVector = function(id) {
  vectorInfo = this.vectorIdToInfo_[id];
  vector = new geometry2d.Vector(0, 0);

  var gamepad = navigator.webkitGamepads[0];
  if (gamepad) {
    vector.x = applyDeadZone_(gamepad.axes[vectorInfo.xAxis]);
    vector.y = applyDeadZone_(-gamepad.axes[vectorInfo.yAxis]);
  }
  return vector;
};

GamepadController.prototype.buttonDown = function(id) {
  return !!this.buttonIdToDown_[id];
};

GamepadController.prototype.lastFrameEventCount = function(id, buttonEvent) {
  var events = this.buttonIdToEvents_[id];
  if (!events) {
    return 0;
  }

  var count = 0;
  for (var i = 0; i < events.length; i++) {
    if (events[i] == buttonEvent) {
      count++;
    }
  }
  return count;
};

GamepadController.prototype.mapVector = function(id, xAxis, yAxis) {
  this.vectorIdToInfo_[id] = {
    xAxis: xAxis,
    yAxis: yAxis
  };
};

GamepadController.prototype.mapButton = function(id, index) {
  this.buttonIdToIndex_[id] = index;
};

GamepadController.prototype.gamepadButtonDownNow_ = function(index) {
  var gamepad = navigator.webkitGamepads[0];
  if (!gamepad) {
    return false;
  }
  return gamepad.buttons[index] == 1;
};

GamepadController.prototype.onResetInputPass_ = function() {
  this.buttonIdToEvents_ = {};
  for (var id in this.buttonIdToIndex_) {
    var downNow = this.gamepadButtonDownNow_(this.buttonIdToIndex_[id]);
    var downBefore = this.buttonIdToDown_[id];
    if (!downBefore && downNow) {
      this.buttonIdToEvents_[id] = [inputconstants.ButtonEvent.PRESS];
    }
    if (downBefore && !downNow) {
      this.buttonIdToEvents_[id] = [inputconstants.ButtonEvent.RELEASE];
    }
    this.buttonIdToDown_[id] = downNow;
  }
};

function applyDeadZone_(value) {
  return Math.abs(value) > 0.1 ? value : 0;
};

return GamepadController;

});
